package com.denghq.projectbuilder.component.remote.service.impl;


import com.denghq.projectbuilder.common.CodeMsg;
import com.denghq.projectbuilder.common.exception.BussinessException;
import com.denghq.projectbuilder.component.remote.cache.CacheManager;
import com.denghq.projectbuilder.component.remote.client.AccountClient;
import com.denghq.projectbuilder.component.remote.client.DepartmentClient;
import com.denghq.projectbuilder.component.remote.client.UserClient;
import com.denghq.projectbuilder.component.remote.client.withtoken.WithTokenUserClient;
import com.denghq.projectbuilder.component.remote.config.properties.PermissonProp;
import com.denghq.projectbuilder.component.remote.model.*;
import com.denghq.projectbuilder.component.remote.pojo.PermissonDepartmentInfo;
import com.denghq.projectbuilder.component.remote.service.SysUserService;
import com.denghq.projectbuilder.component.remote.utils.CloudUtils;
import com.denghq.projectbuilder.component.remote.utils.UserContextHolder;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private PermissonProp permissonProp;

    @Autowired
    private UserClient userClient;

    @Autowired
    private WithTokenUserClient withTokenUserClient;

    @Autowired
    private DepartmentClient departmentClient;

    @Autowired
    private AccountClient accountClient;

    @Override
    public UserRightViewModel getUserInfo() {

        String authorization = UserContextHolder.getAuthorization();
        if (StringUtils.isBlank(authorization)) {
            throw new BussinessException(CodeMsg.API_UNAUTHORIZED, "未登录");
        }

        UserRightViewModel cacheValue = CacheManager.getUserInfo(authorization);
        //如果缓存中有直接返回
        if (cacheValue != null && cacheValue.getUserCode() != null) {
            return cacheValue;
        } else {
            ResultInfoModel<UserRightViewModel> resultInfoModel = userClient.getUserInfo();
            UserRightViewModel userInfo = CloudUtils.getResult(resultInfoModel);
            if (userInfo != null) {
                CacheManager.saveUserInfo(authorization, userInfo);
            }
            return userInfo;

        }

    }

    @Override
    public List<UserModel> findAll() {

        ResultInfoModel<List<UserModel>> infoModel = withTokenUserClient.findAll();
        return CloudUtils.getResult(infoModel);
    }

    @Override
    public String getUserId() {
        UserRightViewModel userInfo = getUserInfo();
        if (userInfo != null) {
            return userInfo.getUserCode();
        }
        return null;
    }

    @Override
    public List<DepartmentModel> getDepartment() {

        ResultInfoModel<List<DepartmentModel>> infoModel = departmentClient.findAll();
        return CloudUtils.getResult(infoModel);
    }

    @Override
    public List<DepartmentModel> getSomeDepartment(List<String> departmentIds) {

        ResultInfoModel<List<DepartmentModel>> infoModel = departmentClient.getSomeDepartment(departmentIds);
        return CloudUtils.getResult(infoModel);
    }

    @Override
    public List<DepartmentModel> getSomeDepartment(Set<String> departmentIds) {
        return getSomeDepartment(new ArrayList<>(departmentIds));
    }

    @Override
    public PermissonDepartmentInfo getPermissonDepartmentInfo(String functionCode, String actionCode) {

        PermissonDepartmentInfo res = new PermissonDepartmentInfo();
        UserRightViewModel userInfo = getUserInfo();

        if (userInfo.getIsAdmin()) {
            res.setFullPermisson(true);
        } else if (hasFA(userInfo.getPermissionList(), functionCode, actionCode)) {
            res.setFullPermisson(true);
        } else {
            res.setFullPermisson(false);
            List<DepartmentModel> departmentList = getGetPermissonDepartmentByFACode(functionCode, actionCode);
            List<String> departmentIdList = Lists.newArrayList();
            if (!CollectionUtils.isEmpty(departmentList)) {
                departmentList.forEach(d -> {
                    departmentIdList.add(d.getDepartmentId());
                });
            }
            res.setDepartmentIdList(departmentIdList);
        }
        return res;
    }

    private List<DepartmentModel> getGetPermissonDepartmentByFACode(String functionCode, String actionCode) {

        ResultInfoModel<List<DepartmentModel>> infoModel = departmentClient.getPermissonDepartmentByFACode(functionCode, actionCode);
        return CloudUtils.getResult(infoModel);

    }

    @Override
    public PermissonDepartmentInfo getSpottingSearchPermissonDepartmentInfo() {
        return getPermissonDepartmentInfo(permissonProp.getSpottingSearchFc(), permissonProp.getSpottingSearchFullDeptAc());
    }

    @Override
    public PermissonDepartmentInfo getFrontdeviceSearchPermissonDepartmentInfo() {
        return getPermissonDepartmentInfo(permissonProp.getFrontdeviceSearchFc(), permissonProp.getFrontdeviceSearchFullDeptAc());
    }

    @Override
    public UserModel getSomeAccountByCode(String userCode) {
        List<UserModel> list = this.getSomeAccountByCode(Arrays.asList(userCode));
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        } else {
            return null;
        }
    }

    public List<UserModel> getSomeAccountByCode(List<String> userCodeList) {

        ResultInfoModel<List<UserModel>> infoModel = accountClient.getSomeAccountByCode(userCodeList);
        return CloudUtils.getResult(infoModel);
    }

    @Override
    public List<String> queryChildDepartmentId(String departmentid) {

        ResultInfoModel<List<String>> infoModel = departmentClient.queryChildDepartmentId(departmentid);
        return CloudUtils.getResult(infoModel);
    }

    private Boolean hasFA(List<PermissionDetailModel> permissionList, String functionCode, String actionCode) {
        if (!CollectionUtils.isEmpty(permissionList)) {
            for (PermissionDetailModel p : permissionList) {
                if (p.getFunctionCode().equals(functionCode)) {
                    List<String> actionCodeList = p.getActionCodeList();
                    if (!CollectionUtils.isEmpty(actionCodeList)) {
                        for (String a : actionCodeList) {
                            if (a.equals(actionCode)) {
                                return true;
                            }
                        }
                    }
                    break;
                }
            }
        }

        return false;
    }
}
